package com.lancoo.cvas.arrangecourse.rulecheck;

import com.lancoo.cvas.arrangecourse.entities.BaseRule;
import com.lancoo.cvas.arrangecourse.entities.ClassHour;
import com.lancoo.cvas.arrangecourse.entities.TeachingClassUnit;
import com.lancoo.cvas.arrangecourse.entities.TimeslotRoom;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @Description 跨校区规则检测
 * @Author Fortysun
 * @Date 2023/9/5 17:02
 **/
public class CrossCampusRuleCheck extends RuleCheck implements RuleDecorator {
    //接收父类的规则服务对象
    private RuleService ruleService;

    public CrossCampusRuleCheck(RuleService ruleService, BaseRule baseRule) {
        this.ruleService = ruleService;
        super.baseRule = baseRule;
    }

    /**
     * 检测是否适合分配：
     * 1、判断是否满足课程分散、集中规则
     * 2、判断是否满足教师分散、集中规则
     * 3、判断是否满足教师单日最大节次安排
     *
     * @param teachingClassUnit 教学班排课单元
     * @param continuousList    连上的教室课时分组信息列表
     * @param classHourMap      课表课时map
     * @return
     */
    @Override
    public Boolean isSuitable(TeachingClassUnit teachingClassUnit,
                              LinkedList<TimeslotRoom> continuousList,
                              ConcurrentHashMap<String, CopyOnWriteArrayList<ClassHour>> classHourMap) {
        //如果上一个增强的规则是符合要求的
        if (ruleService.isSuitable(teachingClassUnit, continuousList, classHourMap)) {
            //进行跨校区规则的检测
            return isCrossCampusSuitable(teachingClassUnit, continuousList, classHourMap);
        }

        return false;
    }

    /**
     * 跨校区排课的规则是否符合要求
     *
     * @param teachingClassUnit
     * @param continuousList
     * @param classHourMap
     * @return
     */
    private Boolean isCrossCampusSuitable(TeachingClassUnit teachingClassUnit,
                                          LinkedList<TimeslotRoom> continuousList,
                                          ConcurrentHashMap<String, CopyOnWriteArrayList<ClassHour>> classHourMap) {
        //如果连上的教室课时分组列表信息为空，或者没有内容
        if (continuousList == null || continuousList.isEmpty()) {
//            log.error("#ProhibitClashCheck.isSuitable#:分配的教室课时分组信息列表为空~！！");
            return false;
        }
        //教学班上课的教师id，多个以逗号分隔
        String teacherIds = teachingClassUnit.getTeacherIds();
        //教学班上课的学生id, 多个以逗号分隔
        String studentIds = teachingClassUnit.getStudentIds();
        //生成教学班的行政班Id
        String phyClassId = teachingClassUnit.getPhyClassId();
        Long teachingClassId = teachingClassUnit.getTeachingClassId();

        //获取列表的第一个教室课时分组对象
        TimeslotRoom timeslotRoom = continuousList.get(0);
        //天编号，01周一、02周二。。。以此类推
        String dayNo = timeslotRoom.getDayNo();
        //半天编号，1上午、2下午、3晚上
        Integer periodType = timeslotRoom.getPeriodType();
        //待分配的教室课时分组，所属的校区id
        String campusId = timeslotRoom.getCampusId();

        List<ClassHour> campusList = new ArrayList<>();
        if ("b".equals(baseRule.getCrossCampusRule())) {
            //获取半天内，其他校区的课表数据
            campusList = getCurHalfDayOtherCampusList(dayNo, periodType, classHourMap, campusId);
        } else if ("c".equals(baseRule.getCrossCampusRule())) {
            //获取一天内，其他校区的课表数据
            campusList = getCurOneDayOtherCampusList(dayNo, classHourMap, campusId);
        }else {
            return true;
        }


        //跨校区排课，学生教师在同一个半天，在不同校区上课情况的判断
        return !isCrossCampusClash(baseRule.getCrossCampusOption(),
                teachingClassId,teacherIds, studentIds, phyClassId, campusList);
    }

    /**
     * 半天内跨校区上课安排
     *
     * @param crossCampusOption 跨校区排课标识，0不跨校区，即各校区独立排课，1跨校区排课
     * @param teacherIds        待分配给教学班的教室课时分组信息列表
     * @param studentIds        已经生成的课表信息
     * @param phyClassId        教学班包含的行政班id
     * @param halfDayCampusList 当前其他校区，当前半天内的已排课表数据（不包含，
     *                          当前待分配的教室课时分组列表，对应的课时编码所对应的分组）
     * @return
     */
    private Boolean isCrossCampusClash(Integer crossCampusOption,
                                       Long teachingClassId,
                                       String teacherIds,
                                       String studentIds,
                                       String phyClassId,
                                       List<ClassHour> halfDayCampusList) {

        Boolean bRet = false;
        //不跨校区
        if (crossCampusOption.equals(0)) {
            bRet = false;
        } else if (crossCampusOption.equals(1)) {//跨校区
            //如果已排课表没数据，那肯定不管分散和集中都是返回false的
            //因为此时没有对比数据
            if (halfDayCampusList == null || halfDayCampusList.isEmpty()) {
                //没有比较数据，肯定就不存在跨校区的问题
                return false;
            }
            //判断当前其他校区，当前半天内的已排课表数据（不包含，当前待分配的教室课时分组列表，对应的课时编码所对应的分组）
            bRet = isClashes(teachingClassId, teacherIds, studentIds, phyClassId, halfDayCampusList);
        }

        return bRet;
    }
}
